package com.oceansoft.mobile.econsole.modules.dcn.processor;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.oceansoft.mobile.econsole.common.spring.SpringContextHolder;
import com.oceansoft.mobile.econsole.modules.dcn.dispatcher.AbstractDispatcher;
import com.oceansoft.mobile.econsole.modules.dcn.entity.Command;
import com.oceansoft.mobile.econsole.modules.dcn.entity.RespCmd;
import com.oceansoft.mobile.econsole.modules.expireWarn.persistence.ExpireWarnMapper;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.OutQueryServiceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

/**
 * ClassName: OuterCoreProcessor
 * Desc: 具体OUT表分发器
 * Date： 2016/11/16
 * Created：shaom
 */
public class OuterCoreProcessor extends AbstractDispatcher {
    private static final Logger logger = LoggerFactory.getLogger(OuterCoreProcessor.class);
    private static HashMap<String, IProcessor> PLUGINS = new HashMap<>();
    @Resource
    private ExpireWarnMapper expireWarnMapper;


    public OuterCoreProcessor(String pluginsPackage, String pluginsName) {
//        registerPlugins(pluginsPackage, pluginsName);
        registerPluginsBean(pluginsPackage, pluginsName);
    }

    private void registerPlugins(String pluginsPackage, String pluginsName) {

        //插件包名
        if (null == pluginsPackage || 0 == pluginsPackage.trim().length()) {
            throw new RuntimeException("读取配置文件插件包路径配置失败 错误:路径不存在或为空!");
        }

        //插件类名
        if (null == pluginsName || 0 == pluginsName.trim().length() || 0 == pluginsName.split(",").length) {
            throw new RuntimeException("读取配置文件已注册插件配置失败 错误:插件类名不存在或为空!");
        }
        String[] pluginClass = pluginsName.split(",");
        for (String clazz : pluginClass) {
            String pluginFullName = String.format("%s.%s", pluginsPackage, clazz);
            try {
                IProcessor plugin = (IProcessor) (Class.forName(pluginFullName).newInstance());
                String command = plugin.command();
                if (null != command && ACTION_PATTERN.matcher(command).matches()) {
                    PLUGINS.put(plugin.command(), plugin);
                    logger.info("插件[{}]注册成功,插件支持命令标识[{}]!", pluginFullName, plugin.command());
                } else {
                    logger.error("插件[{}]注册失败,插件支持命令标识[{}]不正确!", pluginFullName, plugin.command());
                }
            } catch (InstantiationException e) {
                logger.error("插件[{}]注册失败,错误:实例化失败!", pluginFullName);
            } catch (IllegalAccessException e) {
                logger.error("插件[{}]注册失败,错误:实例化失败!", pluginFullName);
            } catch (ClassNotFoundException e) {
                logger.error("插件[{}]注册失败,错误:类未找到!", pluginFullName);
            }
        }
    }

    private void registerPluginsBean(String pluginsPackage, String pluginsName) {
        //插件包名
        if (Strings.isNullOrEmpty(pluginsPackage)) {
            throw new RuntimeException("读取配置文件插件包路径配置失败 错误:路径不存在或为空!");
        }

        //插件类名
        if (Strings.isNullOrEmpty(pluginsName)) {
            throw new RuntimeException("读取配置文件已注册插件配置失败 错误:插件类名不存在或为空!");
        }

        List<String> pluginClass = Splitter.on(",").trimResults().splitToList(pluginsName);

        for (String clazz : pluginClass) {
            String pluginFullName = String.format("%s.%s", pluginsPackage, clazz);
            try {

                Class<?> aClass = Class.forName(pluginFullName);
                IProcessor plugin = (IProcessor) SpringContextHolder.getBean(aClass);
                String command = plugin.command();
                if (null != command && ACTION_PATTERN.matcher(command).matches()) {
                    PLUGINS.put(plugin.command(), plugin);
                    logger.info("插件[{}]注册成功,插件支持命令标识[{}]!", pluginFullName, plugin.command());
                } else {
                    logger.error("插件[{}]注册失败,插件支持命令标识[{}]不正确!", pluginFullName, plugin.command());
                }
            } catch (Exception e) {
                logger.error("插件[{}]注册失败,错误:类未找到!", pluginFullName);
            }
        }
    }


    @Override
    protected RespCmd loadCommand(String rowId) {
        OutQueryServiceInfo out = expireWarnMapper.findOutServiceInfoByRowId(rowId);
        return RespCmdMaker.make(out);
    }

    @Override
    protected IProcessor lookupPlugin(Command command) {
        String action = command.getAction();
        if (null != action && ACTION_PATTERN.matcher(command.getAction()).matches()) {
            if (PLUGINS.containsKey(action))
                return PLUGINS.get(action);
            logger.error("命令:[{}] 加载插件失败,未找到符合当前命令插件!", action);
            return null;
        } else {
            logger.error("命令:[{}] 加载插件失败,当前插件命令标识不正确!", action);
            return null;
        }
    }

    @Override
    protected void resetReqCmd() {
        RespCmdMaker.reset();
    }

    /**
     * 命令对象复用
     */
    private static class RespCmdMaker {
        private static RespCmd cmd = new RespCmd();

        public static RespCmd make(OutQueryServiceInfo rs){
            cmd.setSerialNum(rs.getSn());
            cmd.setAction(rs.getAction());
            cmd.setResult(rs.getRes());
            cmd.setSucc(rs.getSucc().equalsIgnoreCase("Y"));
            cmd.setCode(rs.getCode());
            cmd.setMsg(rs.getMsg());
            cmd.setRespTime(rs.getResp_time());
            return cmd;
        }

        public static void reset() {
            cmd.setSerialNum(null);
            cmd.setAction(null);
            cmd.setResult(null);
            cmd.setSucc(false);
            cmd.setCode(null);
            cmd.setRespTime(null);
        }
    }
}
